#include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>
#include "wrap.h"
#include <arpa/inet.h>
#include "fcntl.h"

#define PORT 8008
int main(int argc,char *argv[]){
    //socket
    int lfd =Socket(AF_INET,SOCK_STREAM,0);
    int on=1;
    if(setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0){
        perror("setsockopt");
    }
    //bind
    struct sockaddr_in serv_addr;
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(PORT);
    serv_addr.sin_addr.s_addr=INADDR_ANY;
    
    Bind(lfd,(struct sockaddr * )&serv_addr,sizeof(serv_addr));
    
    Listen(lfd,128);

    int maxfd=lfd;
    fd_set oldset,newset;
    FD_ZERO(&oldset);
    FD_ZERO(&newset);
    FD_SET(lfd,&oldset);
    
    while(1){

        newset=oldset;
        //监听文件描述符变化
        int n=select(maxfd+1,&newset,NULL,NULL,NULL);
    
        if(n<0){
            perror("");
            break;
        }else if(n==0){
        //没有变化
            continue;
        }else{
        //发生变化
            //lfd发生变化
            if(FD_ISSET(lfd,&newset)){
                struct sockaddr_in cliaddr;
                socklen_t len=sizeof(cliaddr);
                char ip[INET_ADDRSTRLEN];
                int cfd=Accept(lfd,(struct sockaddr*)& cliaddr,&len);
                FD_SET(cfd,&oldset);
                printf("new client ip= %s port= %d\n" ,inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,16),ntohs(cliaddr.sin_port));

                if(cfd>maxfd)
                    maxfd=cfd;
                if(--n==0)
                    continue;
            }
            //cfd发生变化
            for(int i=lfd+1;i<=maxfd;i++){
                if(FD_ISSET(i,&newset)){
                    char buf[1024]="";
                    int ret=Read(i,buf,sizeof(buf));
                    if(ret<0){
                        perror("");
                        close(i);
                        FD_CLR(i,&oldset);
                    }else if(ret==0){
                        printf ("client close\n");
                        close(i);
                        FD_CLR(i,&oldset);
                    }else{
                        printf("write  %s",buf);
                //        Write(i,buf,ret);
                    }
                }
            }
        }
    }
    close(lfd);
    return 0;
}

